package com.pronhub.luowowo.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.pronhub.luowowo.article.domain.StrategyDetail;
import com.pronhub.luowowo.article.service.IStrategyDetailService;
import com.pronhub.luowowo.service.IStrategyStatisRedisService;
import com.pronhub.luowowo.util.BeanUtilLXY;
import com.pronhub.luowowo.util.DateUtil;
import com.pronhub.luowowo.util.Rediskey;
import com.pronhub.luowowo.vo.StrategyStatisVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class StrategyStatisRedisServiceImpl implements IStrategyStatisRedisService {
    public static final int STRATEGY_TYPE_VIEWNUM = 1;  //阅读量
    public static final int STRATEGY_TYPE_REPLYNUM = 2;  //回复量
    public static final int STRATEGY_TYPE_FAVORNUM = 3;  //收藏量
    public static final int STRATEGY_TYPE_SHARENUM = 4;  //分享量
    public static final int STRATEGY_TYPE_THUMBSUPNUM = 5;  //点赞量


    @Autowired
    private StringRedisTemplate template;
    @Reference
    private IStrategyDetailService strategyDetailService;
    @Override
    public void viewNumIncrease(Long sid, int i) {
        numIncrease(sid,i,STRATEGY_TYPE_VIEWNUM);
    }

    @Override
    public StrategyStatisVO getStrategyStatisVo(Long sid) {
        String key = Rediskey.STRATEGY_STATIS_VO.getKeys(sid.toString());
        StrategyStatisVO vo = null;
        if (template.hasKey(key)){
            String voStr = template.opsForValue().get(key);
            vo = JSON.parseObject(voStr,StrategyStatisVO.class);
        }else {
            vo = new StrategyStatisVO();
            StrategyDetail detail = strategyDetailService.get(sid);

            //属性拷贝
            BeanUtilLXY.copyProperties(vo,detail);
            vo.setDestId(detail.getDest().getId());
            vo.setDestName(detail.getDest().getName());
            vo.setStrategyId(detail.getId());
            template.opsForValue().set(key,JSON.toJSONString(vo));
        }

        return vo;
    }

    @Override
    public void replyNumIncrease(Long detailId, int i) {
        numIncrease(detailId, i, STRATEGY_TYPE_REPLYNUM);

    }

    @Override
    public boolean favor(Long sid, Long uid) {
        boolean flag = false;
        //当前用户是否收藏了这个文章
        String key = Rediskey.STRATEGY_STATIS_FAVOR.getKeys(sid.toString());
        List<Long> userId = null;
        if (template.hasKey(key)){
            //攻略的收藏用户有那个
            String listStr = template.opsForValue().get(key);
            userId = JSON.parseArray(listStr, Long.class);
        }else {
            //没用攻略的
            userId =new ArrayList<>();
        }

        StrategyStatisVO vo = this.getStrategyStatisVo(sid);
        if (userId.contains(uid)){
            //已经收藏的话 取消收藏
            vo.setFavornum(vo.getFavornum() -1);
            userId.remove(uid);
        }else {
            //没有收藏的话 +1
            vo.setFavornum(vo.getFavornum() +1);
            userId.add(uid);
            flag = true;
        }
        //统一更新
        template.opsForValue().set(key, JSON.toJSONString(userId));
        //vo 的更新
        String vokey = Rediskey.STRATEGY_STATIS_VO.getKeys(sid.toString());
        template.opsForValue().set(vokey, JSON.toJSONString(vo));
        return flag;
    }

    @Override
    public boolean thumbup(Long sid, Long id) {
        //1得到Key
        String key = Rediskey.STRATEGY_STATIS_THUMBSUPNUM.getKeys(sid.toString(), id.toString());
        //如果存在
        if (!template.hasKey(key)){
            //如果没有 点赞数+1
            this.numIncrease(sid,1,STRATEGY_TYPE_THUMBSUPNUM);
            Date endDate = DateUtil.getEndDate(new Date());
            long dateBetween = DateUtil.getDateBetween(new Date(),endDate);
            //主要要Key值
            template.opsForValue().set(key,"1",dateBetween, TimeUnit.SECONDS);
            return true;
        }

        //有的话就点赞过的
        return false;
    }

    @Override
    public void setStrategyStatisVO(StrategyStatisVO vo) {
        //需要得到Key和JSON数值才能往Redis里面放
        String key = Rediskey.STRATEGY_STATIS_VO.getKeys(vo.getStrategyId().toString());
        template.opsForValue().set(key,JSON.toJSONString(vo));
    }

    @Override
    public boolean isStrategyStatisVOExsit(Long id) {
        String key = Rediskey.STRATEGY_STATIS_VO.getKeys(id.toString());
       if (template.hasKey(key)){
           return true;
       }
       return false;
    }

    @Override
    public List<StrategyStatisVO> getStrategyStatisVOS(String pattern) {
        //在Redis里面有一个方法 就是根据一小点的Key就可以的得到一整个LIst
        // keys strategy_statis_vo:* 得到这个钥匙串开头的所有钥匙
        Set<String> keys = template.keys(pattern);
        List<StrategyStatisVO> list = new ArrayList<>();
        for (String key : keys) {
            String voStr = template.opsForValue().get(key);
            StrategyStatisVO vo = JSON.parseObject(voStr, StrategyStatisVO.class);
            list.add(vo);
        }
        return list;
    }

    @Override
    public void addCommendScores(String value, int score) {
        //攻略的
        String key = Rediskey.STRATEGY_ZSET_SORT_COMMEND.getPrefix();
        template.opsForZSet().incrementScore(key,value,score);
    }

    @Override
    public void addHotScores(String value, int score) {
        //得到他的开头
        String key = Rediskey.STRATEGY_ZSET_SORT_HOT.getPrefix();

        template.opsForZSet().incrementScore(key,value,score);


    }

    @Override
    public List<StrategyStatisVO> getAllVOByZset() {
        //zset的Key

        String key = Rediskey.STRATEGY_ZSET_SORT_COMMEND.getPrefix();
        List<StrategyStatisVO> list = new ArrayList<>();

        Set<String> set = template.opsForZSet().reverseRange(key, 0, -1);
        for (String voKey : set) {
            String voStr = template.opsForValue().get(voKey);
            list.add(JSON.parseObject(voStr,StrategyStatisVO.class));
        }
        return list;
    }

    @Override
    public List<StrategyStatisVO> getHotTop10() {
        //需要从Redis里面获取对应的热门参数
        String key = Rediskey.STRATEGY_ZSET_SORT_HOT.getPrefix();
        List<StrategyStatisVO> list =new ArrayList<>();
        Set<String> zset = template.opsForZSet().reverseRange(key, 0, 9);
        for (String vokey : zset) {
            String voStr = template.opsForValue().get(vokey);

            StrategyStatisVO vo = JSON.parseObject(voStr, StrategyStatisVO.class);
            list.add(vo);
        }
        return list;
    }

    @Override
    public boolean isZsetHasValue(String key, String value) {

        Long rank = template.opsForZSet().rank(key, value);

        return rank != null;
    }
    private void numIncrease(Long sid,int num,int type){
        //判断这个Key是否存在Redis中 使得话就查出来 不是的话就就进行初始化
        String key = Rediskey.STRATEGY_STATIS_VO.getKeys(sid.toString());
        StrategyStatisVO vo = this.getStrategyStatisVo(sid);
        switch (type){
            case STRATEGY_TYPE_VIEWNUM:
                vo.setViewnum(vo.getViewnum() + num);
                break;
            case STRATEGY_TYPE_REPLYNUM:
                vo.setReplynum(vo.getReplynum() + num);
                break;
            case STRATEGY_TYPE_FAVORNUM:
                vo.setFavornum(vo.getFavornum() + num);
                break;
            case STRATEGY_TYPE_SHARENUM:
                vo.setSharenum(vo.getSharenum() + num);
                break;
            case STRATEGY_TYPE_THUMBSUPNUM:
                vo.setThumbsupnum(vo.getThumbsupnum() + num);
                break;
        }
        //统一存到Redis里边
        template.opsForValue().set(key, JSON.toJSONString(vo));
    }
}
